﻿using System.Collections.Generic;
using System.Web.Mvc;
using MugenInjection.Infrastructure;
using MugenInjection.Interface;

namespace MugenInjection.Web.Mvc
{
    /// <summary>
    ///     Filter provider that gets the filters form the attributes of the actions.
    /// </summary>
    public class MugenInjectionFilterAttributeFilterProvider : FilterAttributeFilterProvider
    {
        #region Fields

        private readonly IInjector _injector;

        #endregion

        #region Constructors

        /// <summary>
        ///     Initializes a new instance of the <see cref="MugenInjectionFilterAttributeFilterProvider" /> class.
        /// </summary>
        public MugenInjectionFilterAttributeFilterProvider(IInjector injector)
        {
            Validate.ArgumentNotNull(injector, "injector");
            _injector = injector;
        }

        #endregion

        #region Overrides of FilterAttributeFilterProvider

        /// <summary>
        ///     Gets a collection of custom action attributes.
        /// </summary>
        /// <returns>
        ///     A collection of custom action attributes.
        /// </returns>
        /// <param name="controllerContext">The controller context.</param>
        /// <param name="actionDescriptor">The action descriptor.</param>
        protected override IEnumerable<FilterAttribute> GetActionAttributes(ControllerContext controllerContext,
                                                                            ActionDescriptor actionDescriptor)
        {
            IEnumerable<FilterAttribute> attrs = base.GetActionAttributes(controllerContext, actionDescriptor);
            if (attrs == null)
                return null;
            foreach (FilterAttribute attribute in attrs)
            {
                FilterAttribute attr = attribute;
                _injector.Inject(ref attr);
            }
            return attrs;
        }

        /// <summary>
        ///     Gets a collection of controller attributes.
        /// </summary>
        /// <returns>
        ///     A collection of controller attributes.
        /// </returns>
        /// <param name="controllerContext">The controller context.</param>
        /// <param name="actionDescriptor">The action descriptor.</param>
        protected override IEnumerable<FilterAttribute> GetControllerAttributes(ControllerContext controllerContext,
                                                                                ActionDescriptor actionDescriptor)
        {
            IEnumerable<FilterAttribute> attrs = base.GetControllerAttributes(controllerContext, actionDescriptor);
            if (attrs == null)
                return null;
            foreach (FilterAttribute attribute in attrs)
            {
                FilterAttribute attr = attribute;
                _injector.Inject(ref attr);
            }
            return attrs;
        }

        /// <summary>
        ///     Aggregates the filters from all of the filter providers into one collection.
        /// </summary>
        /// <returns>
        ///     The collection filters from all of the filter providers.
        /// </returns>
        /// <param name="controllerContext">The controller context.</param>
        /// <param name="actionDescriptor">The action descriptor.</param>
        public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext,
                                                       ActionDescriptor actionDescriptor)
        {
            IEnumerable<Filter> filters = base.GetFilters(controllerContext, actionDescriptor);
            if (filters == null)
                return null;
            foreach (Filter filter in filters)
            {
                Filter f = filter;
                _injector.Inject(ref f);
            }
            return filters;
        }

        #endregion
    }
}